<?php

declare(strict_types=1);

namespace App\Controller\Home\Drp;


use App\Constants\ErrorCode;
use App\Model\ChargeOption;
use App\Model\Device;
use App\Model\Order;
use App\Model\Station;
use App\Model\StationClass;
use App\Services\DeviceService;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Trait\ResponseMsg;
use App\Model\Normal;
use Hyperf\Di\Annotation\Inject;
use Util\Common;
use App\Controller\AbstractController;
use App\Model\Distributors;

class HomeStationController extends AbstractController
{
    use ResponseMsg;

    protected Redis $redis;
    protected Normal $normal;

    #[Inject]
    protected Station $station;


    #[Inject]
    protected Distributors $distributors;

    #[Inject]
    protected Device $device;

    public function __construct()
    {
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
    }

    /**站点分类列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function classList(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        $classList = StationClass::query()
            ->where('distributor_id', $info['id'])
            ->with('station')
            ->withCount('station')
            ->get();
        return $this->success($classList);
    }

    /**获取站点未分组的站点列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    /**获取站点未分组的站点列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function stationNoClass(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }

        $stationList = Station::query();
        $keyword = $request->input('keyword');
        if ($keyword) {
            $stationList->where('name', 'like', "%{$keyword}%");
        }
        $stationList = $stationList->where('distributor_id', $info['id'])
            ->where('class_id', 0)
            ->select(['id', 'name']) // 明确指定要选择的字段
            ->withCount('device') // 添加设备计数
            ->get();
        return $this->success($stationList);
    }


    public function removeStationClass(RequestInterface $request): ResponseInterface
    {
        $id = $request->input('station_id');
        $station = Station::query()->where('id', $id)->first();
        if(!$station){
            return $this->error(code: 1001, msg: '站点不存在');
        }
        $station->class_id = 0;
        $station->save();
        return $this->success();
    }

    public function batchRemoveClass(RequestInterface $request):ResponseInterface{
        $ids = $request->input('stations');
        if(!$ids){
            return $this->error(code: 1001, msg: '请选择站点');
        }
        if(!is_array($ids)){
            $ids = json_decode($ids,true);
        }
       Station::query()->whereIn('id', $ids)->update(['class_id' => 0]);
        return $this->success();
    }


    public function createClass(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $label = $request->input('label');
        $id = $request->input('id');
        if ($id > 0) {
            $class = StationClass::query()->where('id', $id)->first();
        } else {
            $class = new StationClass();
        }
        $class->label = $label;
        $class->distributor_id = $info['id'];
        $class->save();
        return $this->success();
    }

    public function removeClass(RequestInterface $request): ResponseInterface
    {
        $id = $request->input('class_id');
        $class = StationClass::query()->where('id', $id)->first();
        if (!$class) {
            return $this->error(code: 1001, msg: '分类不存在');
        }
        $class->delete();
        $this->station->where('class_id', $id)->update(['class_id' => 0]);
        return $this->success();
    }


    public function setClass(RequestInterface $request): ResponseInterface
    {
        $id = $request->input('class_id');
        $class = StationClass::query()->where('id', $id)->first();
        if (!$class) {
            return $this->error(code: 1001, msg: '分类不存在');
        }
        $stations = $request->input('stations');
        $this->station->whereIn('id', $stations)->update(['class_id' => $id]);
        return $this->success();
    }


    /**修改套餐
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function changeCharge(RequestInterface $request): ResponseInterface
    {
        $station_id = $request->input('station_id');
        $charge_id = $request->input('charge_id');
        $station = $this->station->where('id', $station_id)->first();
        if (!$station) {
            return $this->error(code: 1001, msg: '站点不存在');
        }
        $station->charge_id = $charge_id;
        $station->save();
        return $this->success();
    }

    /**修改退款
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function changeRefund(RequestInterface $request): ResponseInterface
    {
        $station_id = $request->input('station_id');
        $is_refund = $request->input('is_refund');
        $station = $this->station->where('id', $station_id)->first();
        if (!$station) {
            return $this->error(code: 1001, msg: '站点不存在');
        }
        $station->is_refund = $is_refund ?? 0;
        $station->save();
        return $this->success();
    }


    /**解绑设备
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function unbindDevice(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $sn = $request->input('sn');
        if (is_string($sn)) {
            $sn = trim($sn);
        }
        if (!$sn) {
            return $this->error(code: 1002, msg: '设备不存在');
        }
        try {
            $device = $this->device->where('sn', $sn)->first();
            $device->station_id = 0;
            $device->save();
            return $this->success();
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1001, msg: $e->getMessage());
        }
    }


    /**添加编辑站点
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function create(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $params = $request->inputs(['address', 'name', 'images','charge_id',
                'lat', 'lng', 'province', 'city', 'area',
                'province_code','class_id','is_refund',
                'city_code', 'area_code', 'remark', 'id']);
            if(!$params['charge_id']){
                $params['charge_id'] = ChargeOption::where('distributor_id', 0)
                    ->where('is_del', 1)
                    ->orderBy('sort', 'desc')
                    ->value('id');
            }
            if ($params['id'] > 0) {
                $station = $this->station->where('id', $params['id'])->first();
                if (!$station) {
                    return $this->error(1001, '站点不存在');
                }
            } else {
                $station = new Station();
            }
            if (!$params['name']) {
                return $this->error(code: 1002, msg: '电站名称不能为空');
            }
            if (!$params['area_code']) {
                return $this->error(code: 1002, msg: '请至少定位到包含区/县信息');
            }
            if (!$params['lat'] || !$params['lng']) {
                return $this->error(code: 1002, msg: '经纬度不能为空');
            }

            if (!$params['address']) {
                return $this->error(code: 1002, msg: '详细地址不能为空');
            }
            $station->distributor_id = $info['id'];
            $station->name = $params['name'];
            $station->lat = $params['lat'];
            $station->lng = $params['lng'];
            $station->address = $params['address'];
            $station->province = $params['province'] ?? '';
            $station->province_code = $params['province_code'] ?? '';
            $station->city = $params['city'] ?? '';
            $station->city_code = $params['city_code'] ?? '';
            $station->area = $params['area'] ?? '';
            $station->area_code = $params['area_code'] ?? '';
            $station->remark = $params['remark'] ?? '';
            $station->charge_id = $params['charge_id'];
            $station->class_id = $params['class_id'] ?? 0;
            $station->is_refund = $params['is_refund'] ?? 1;
            if (isset($params['images']) && !empty($params['images'])) {
                if (is_array($params['images']) && count($params['images'])>0 ) {
                    $station->images = json_encode($params['images']);
                } elseif (is_string($params['images'])) {
                    // 如果已经是字符串，检查是否为有效的JSON
                    $decoded = json_decode($params['images'], true);
                    if (json_last_error() === JSON_ERROR_NONE) {
                        $station->images = $params['images'];
                    } else {
                        $station->images = json_encode([$params['images']]); // 作为单个元素的数组处理
                    }
                }
            }

            $station->save();
            Device::removeStation($station->id . '');
            Device::addStation($station->id . '', (float)$station->lng, (float)$station->lat);
            return $this->success($station);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1001, msg: $e->getMessage());
        }
    }

    /**绑定设备
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    /**绑定设备
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function bindDevice(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }

        $params['sn'] = $request->input('sn');
        $params['station_id'] = $request->input('station_id');
        if (is_string($params['sn'])) {
            $params['sn'] = trim($params['sn']);
        }
        $device = $this->device->where('sn', $params['sn'])->first();
        if (!$device) {
            return $this->error('1002', '该设备编号不存在');
        }
        if ($device->station_id > 0) {
            return $this->error('1002', '该设备已绑定站点 请先解绑');
        }
        try{
            $deviceDistributor = $this->distributors->where('id', $device->distributor_id)->first();
            if($deviceDistributor){
                if($deviceDistributor->level == Distributors::LEVEL_2){
                    return $this->error('1002', '设备已绑定二级经销商，请先解绑');
                }
            }else{
                return $this->error('1002', '设备未出厂划拨，请联系客服');
            }
            if ($info['level'] == Distributors::LEVEL_1) {
                if ($device->distributor_id != $info['id']) {
                    return $this->error(1002, '该设备已绑定其他一级分销商');
                }
            } else {
                $distributor = $this->distributors->where('id', $info['id'])->first();
                // 添加空值检查
                if (!$distributor) {
                    return $this->error(1002, '分销商信息不存在'.$info['id']);
                }

                if ($distributor->parent_id <= 0) {
                    $distributor->parent_id = $device->distributor_id;
                    $distributor->save();
                }
                if ($device->distributor_id > 0 && $distributor->parent_id > 0 && $distributor->parent_id != $device->distributor_id) {
                    return $this->error(1002, '设备归属异常 请联系管理员');
                }
            }
            $device->distributor_id = $info['id'];
            $device->station_id = $params['station_id'];
            $device->bind_at = date('Y-m-d H:i:s');
            $device->save();
            return $this->success();
        }catch (\Exception $e){
            return $this->error(code: 1001, msg: $e->getMessage().$e->getTraceAsString());
        }
    }


    public function getUnbind(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        $keyword = $request->input('keyword');
        $page = $request->input('page', 1);
        $pageSize = $request->input('page_size', 10);
        $query = $this->device->where('distributor_id', $info['id']);
        if($keyword){
            $query->where('sn', 'like', '%' . $keyword . '%');
        }
        $device = $query->where('distributor_id', $info['id'])
            ->where('station_id',0)->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            ->get(['id','sn']);
        return $this->success($device);
    }

    /**电站列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function list(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $keyword = $request->input('keyword');
        $class_id = $request->input('class_id');
        $query = $this->station->where('distributor_id', $info['id']);

        if (!empty($keyword)) {
            $query->where('name', 'like', '%' . $keyword . '%');
        }
        if (!empty($class_id)) {
            $query->where('class_id', $class_id);
        }
        $list = $query
            ->with('charge', 'charge.time_children', 'charge.power_children', 'charge.service_children','stationClass')
            ->withCount('device')->get();
        return $this->success($list);
    }

    public function getAll(RequestInterface $request){
        $info = $this->distributors->getInfo($request);
        $query = $this->station->where('distributor_id', $info['id']);
        if (!empty($keyword)) {
            $query->where('name', 'like', '%' . $keyword . '%');
        }
        if (!empty($class_id)) {
            $query->where('class_id', $class_id);
        }
        $list = $query->select('id', 'name')->get();
        return $this->success($list);
    }


    public function devices(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $keyword = $request->input('keyword');
        $station_id = $request->input('station_id');
        $query = $this->device->where('distributor_id', $info['id']);
        if (!empty($keyword)) {
            $query->where('sn', 'like', '%' . $keyword . '%');
        }
        if (!empty($station_id)) {
            $query->where('station_id', $station_id);
        }
        $list = $query->select('id', 'sn', 'fd')->get();
        return $this->success($list);
    }

    public function choseList(RequestInterface $request)
    {
        $station_id = $request->input('station_id');
        $list = $this->device->where('station_id', $station_id)->pluck('id')->toArray();
        return $this->success($list);
    }

    public function batchChose(RequestInterface $request)
    {
        $devices = $request->input('devices');
        $station_id = $request->input('station_id');
        if(!$devices){
            return $this->error(1001, '请选择设备');
        }
        if(!is_array($devices)){
            $devices = json_decode($devices, true);
        }
        $this->device->whereIn('id', $devices)->update(['station_id' => $station_id]);
        return $this->success();
    }

    public function detail(RequestInterface $request): ResponseInterface
    {
        $id = $request->input('station_id', 0, 'int');
        if (!$id) {
            return $this->error(ErrorCode::PARAMS_ERR);
        }
        $data = $this->station->where('id', $id)
            ->with('charge', 'charge.time_children', 'charge.power_children', 'charge.service_children')->first();
        return $this->success($data);
    }


    public function del(RequestInterface $request): ResponseInterface
    {
        $id = $request->input('station_id', 0, 'int');
        if (!$id) {
            return $this->error(ErrorCode::PARAMS_ERR);
        }
        $check = $this->device->where('station_id', $id)->count();
        if ($check) {
            return $this->error(1001, '请先解绑电站下的设备信息');
        }

        $station = $this->station->where('id', $id)->first();
        if (!$station) {
            return $this->error(1001, '电站不存在');
        }
        $station->delete();
        return $this->success();
    }


    /**关闭订单并结束充电
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function stopOrder(RequestInterface $request): ResponseInterface
    {
        $sn = $request->input('sn', 0, 'int');
        $channel = $request->input('channel_number', 0, 'int');
        $type = $request->input('type', 1, 'int');
        $orderModel = Order::query()->with('device')->where('sn',$sn)
            ->where('channel_number',$channel)
            ->where('status',Order::STATUS_USING)
            ->orderBy('id','desc')
            ->first();

        if (!$orderModel) {
            return $this->error('订单不存在');
        }
        if ($type == 1) {
            $orderModel->duration_seconds = $orderModel->getDurationSeconds();
            $orderModel->save();
            $data = [
                'fd' => $orderModel->device->fd,
                'sn' => $orderModel->device->sn,
                'channel_number' => $orderModel->channel_number,
                'number' => $orderModel->number,
                'balance' => 0
            ];
            $response = DeviceService::postTcp('/tcp/stop', $data);
            $responseData = json_decode($response->getBody()->getContents(), true);
            if ($response->getStatusCode() == 200) {
                if ($responseData['code'] == 200) {
                    Db::commit();
                    return $this->success(msg: '结束成功');
                } else {
                    Db::rollBack();
                    return $this->error(1001, $responseData['msg'] ?? '关闭发送失败');
                }
            } else {
                Db::rollBack();
                return $this->error(1001, '关闭发送失败: ' . ($responseData['message'] ?? '未知错误'));
            }
        } else {
            $orderModel->offStop('设备离线结单');
            return $this->success(msg: '结束成功');
        }
    }

}
